/*
 * @(#)Item.java 1.0 22 Sep 2007
 *
 * Copyright (c) 2005-2007 Soluciones Info Móviles S.A.C.
 * Av. Javier Prado Oeste 203 - Piso 13, Lima 27, Perú.
 * Todos los derechos reservados.
 */
package sim.framework.modules.business;

import java.util.*;
import sim.store.*;

import sim.framework.*;
import sim.utils.*;


/**
 * Clase abstracta que permite el almacenamiento y consulta de elementos
 * del detalle de una operación (business).
 *
 * @since     1.0
 */
public abstract class Item {
    
    private static final int FIELD_PRIMARYKEY = 0;
    private static final int FIELD_TOTAL = 1;
    
    private Simlet m_Simlet;    
    private DataTxt m_Record = null;
    
    /**
     * Crea una nueva instancia de la clase.
     */
    public Item(Simlet s, int nFields) {
        m_Simlet = s;
        nFields  = Math.max(nFields, DocDetail.FIELD_TOTAL + 1);
        m_Record = new DataTxt(Utils.TOKEN, Utils.TOKEN_PIPE, 1, nFields, s.getAppEncoding());
    }
    
    /**
     * Setea la llave primaria del elemento.
     *
     * @param primaryKey    flujo de bytes que contiene la llave
     *                      primaria.
     */
    protected final void setPrimaryKey(byte[] primaryKey) {
        if (m_Record.empty(FIELD_PRIMARYKEY)) {
            m_Record.set(FIELD_PRIMARYKEY, primaryKey);
        }
    }
    
    
    /**
     * Indica si la data almacenada en una determinada posición está
     * vacía.
     *
     * @param indexField    índice del campo a consultar.
     */
    public final boolean empty(int indexField) {
        return m_Record.empty(Item.FIELD_TOTAL + indexField);
    }
    
    /**
     * Setea un flujo de bytes en una posición determinada.
     *
     * @param indexField    índice del campo a setear.
     * @param line          flujo de bytes que contiene el valor del campo.
     * @param start         posición de inicio de la data válida.
     * @param count         tamaño de la data válida.
     */
    public final void set(int indexField, final byte[] line, int start, int count) {
        m_Record.set(Item.FIELD_TOTAL + indexField, line, start, count);
    }
    
    /**
     * Setea un flujo de bytes en una posición determinada.
     *
     * @param indexField    índice del campo a setear.
     * @param line          flujo de bytes que contiene el valor del campo.
     */
    public final void set(int indexField, final byte[] line) {
        m_Record.set(Item.FIELD_TOTAL + indexField, line, 0, line.length);
    }
    
    /**
     * Setea una cadena de texto en una posición determinada.
     *
     * @param indexField    índice del campo a setear.
     * @param value         cadena de texto que contiene el valor del campo.
     */
    public final void set(int indexField, final String value) {
        m_Record.set(Item.FIELD_TOTAL + indexField, value);
    }
    
    /**
     * Setea un valor entero en una posición determinada.
     *
     * @param indexField    índice del campo a setear.
     * @param value         entero contiene el valor del campo.
     * @param base          base en que se encuentra representado el número.
     */
    public final void set(int indexField, int value, int base) {
        m_Record.set(Item.FIELD_TOTAL + indexField, value, base);
    }
    
    /**
     * Setea un valor double en una posición determinada.
     *
     * @param indexField    índice del campo a setear.
     * @param value         double contiene el valor del campo.
     */
    public final void set(int indexField, double value) {
        m_Record.set(Item.FIELD_TOTAL + indexField, value);
    }
    
    /**
     * Recupera el campo de una posición determinada como flujo de bytes
     *
     * @param indexField    índice del campo a setear.
     * @return              flujo de bytes que contiene al campo.
     */
    public final byte[] getBytes(int indexField){
        return m_Record.getBytes(Item.FIELD_TOTAL + indexField);
    }
    
    /**
     * Recupera el campo de una posición determinada como cadena de 
     * texto.
     *
     * @param indexField    índice del campo a setear.
     * @return              cadena de texto que contiene al campo.
     */
    public final String getString(int indexField){
        return m_Record.getString(Item.FIELD_TOTAL + indexField);
    }

    /**
     * Recupera el campo de una posición determinada como cadena de 
     * texto.
     *
     * @param indexField    índice del campo a setear.
     * @return              cadena de texto que contiene al campo.
     */
    public final double getDouble(int indexField){
        return m_Record.getDouble(Item.FIELD_TOTAL + indexField);
    }
    
    /**
     * Almacena el contenido de su <code>DataTxt</code> en disco.
     *
     * @param table tabla en donde se almacena el item.
     * @return      <code>true</code> si se pudo almacenar la data y 
     *              <code>false</code> en caso contrario.
     */
    protected final boolean save(StoreTxt table) {
        boolean ret = true;
        if (modified()) {
            ret = false;
            if (table.save(m_Record)) {
                ret = true;
                m_Record.setModified(false);
            }
        }
        return ret;
    }
    
    /**
     * Indica si el item ha sido modificado.
     *
     * @return      <code>true</code> si fue modificado el item y 
     *              <code>false</code> en caso contrario.
     */    
    public final boolean modified() {
        return m_Record.modified();
    }
}
